/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package view;

import ejb.EntityManagement;
import entity.Article;
import entity.Groups;
import entity.Post;
import entity.User;
import entity.Version;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
import javax.inject.Inject;

/**
 *
 * @author Raphael
 */
@ManagedBean
@RequestScoped
//@SessionScoped
public class ArticleBean implements Serializable {

    private static final String INDEX = "/add/index.xhtml";
    private static final String EDIT = "/edit/edit.xhtml";
    private static final String SINGLE = "/add/single.xhtml";
    private static final String CREATE ="/edit/create.xhtml";
    private static final String SEARCHRESULT ="/add/searchResult.xhtml";
    private static final String LOGIN="/add/login.xhtml";
    private static final String IMPRESSUM="/add/impressum.xhtml";
    private static final String KONTAKT="/add/kontakt.xhtml";
    private static final String REGIST="/add/regist.xhtml";
    private static final long serialVersionUID = 1L;
    private Article article;
    private Post post;
    private Version oldVersion;
    private String articleThema;
    private String postText;
    private String postSubhead;
    private String searchText;
    @Inject
    private EntityManagement em;

    public ArticleBean() {
    }

    /**
     * Ruft die zu editierenden Daten aus der Datenbank ab und zeigt sie
     * editierbar in einer Textarea an
     *
     * @author Raphael
     * @param post
     *
     * @return Leitet einen auf die edit.xhtml um
     */

    public String edit(Post post) {
  
        String aid,vid;
        aid = getRequestParameter("id");
        vid = getRequestParameter("versionid");
        if (aid != null) {
           searchArticle(aid);
        }
         if (vid != null) {
           oldVersion = article.getVersion(Integer.parseInt(vid) - 1);
        }
        this.post=post;
        setPostText(post.getPost());
        setPostSubhead(post.getSubheading());
        return EDIT;
    }
    
    /**
     * Sucht den Angegebenen String in der Datenbank und Leitet den User auf eine
     * angemessene Seite weiter. Bei keinem Ergebnis wird die Index.xhtml wieder aufgerufen.
     * Bei einem ergebnis wird direkt auf die entsprechende Indexseite weitergeleitet.
     * Bei mehreren Ergebnissen wird die searchResult.xhtml aufgerufen welche alle 
     * Ergebnisse auf einer Seite auflistet. 
     * 
     * Bei dieser methode wird der Parameter über POST in der Variable searchText 
     * gespeichert.
     *
     * @author Patrick 
     *
     * @return Leitet einen auf die Entsprechende Seite weiter
     */
    public String search(){
        if(searchText==null){
            searchText=getRequestParameter("searchText");
        }
        List<Article> searchResult = em.searchArticle(searchText);
        System.err.println("Ergebnisse: "+searchResult.size()+" mit "+searchText);
        if((searchResult.isEmpty())){
            return INDEX;
        }        
        else if(searchResult.size()==1){
            this.article=searchResult.get(0);
            return SINGLE;
        }else{
            return SEARCHRESULT;
        }
        
    }    
    
      
    /**
     * Sucht einen zufälligen Article aus der Datenbank raus. 
     *
     * @author Patrick
     *
     * @return Leitet auf den Artikel weiter
     * @throws Leitet bei Fehler auf INDEX weiter.
     */
      public String random(){
        Article randomResult;
        try{
            randomResult = em.randomArticle();
        }catch(Exception e){
            return INDEX;
        }
            this.article=randomResult;
            return SINGLE;
        }
        
      /**
     * Sucht neu erstellen Article aus der Datenbank. Dies geschied indem einfach
     * der Artikel mit der Größten ID genommen wird.
     *
     * @author Patrick
     *
     * @return Leitet auf entsprechenden Artikel weiter
     * @throws Leitet bei Fehler auf INDEX weiter.
     */
       public String latestArticle(){
        Article lArticle;
           try{
           lArticle = em.latestArticle();
           }catch(Exception e){
            return INDEX;
        }
        if(lArticle==null){
            return INDEX;
        }
        else {
            this.article=lArticle;
            return SINGLE;
        }
        
    }
    public List<Article> searchArticleList(){
        String sText;
        sText = getRequestParameter("searchText");
      
        if (sText != null) {
           searchText=sText;
        }
        return em.searchArticle(searchText);
    }
    
    public String createPost(){
        
        Article newArticle = new Article(articleThema);
        Date date = new Date();
        List<Post> posts = new ArrayList();
        newArticle.addVersions(new Version(1, true, date, posts));        
        em.persist(newArticle);
        article=newArticle;
        return SINGLE;
    }
    public String create(){
        return CREATE;
    }
     public String addPost() {
  
        String aid,vid;
        aid = getRequestParameter("id");
        vid = getRequestParameter("versionid");
        if (aid != null) {
           searchArticle(aid);
        }
         if (vid != null) {
           oldVersion = article.getVersion(Integer.parseInt(vid) - 1);
        }
        this.post=new Post("","","");
        setPostText(post.getPost());
        return EDIT;
    }

    /**
     * Editiert den Artikel
     *
     * @author Raphael, Patrick
     *
     * @return Link auf geänderten Article
     */
    public String change(User user) {          
        System.err.println("hierk komme isch schonma an");
        user=em.getUser(user.getUser_name());
        String aid,vid,pid;
        aid = getRequestParameter("id");
        vid = getRequestParameter("oldversionid");
        pid = getRequestParameter("postid");
        if (aid != null) {
             System.err.println("hierk komme isch schonma an 1");
           searchArticle(aid);
        }
         if (vid != null) {
              System.err.println("hierk komme isch schonma an 2");
           oldVersion = article.getVersion(Integer.parseInt(vid) - 1);
        }
         if (pid != null) {       
              System.err.println("hierk komme isch schonma an 3");
           if(searchPost(pid)==null){
               this.post=new Post("","","");
           }
        }
        
        List<Post> oldPosts = oldVersion.getPosts();
	
        List<Post> newPosts=new ArrayList();
        String Picturepfad="";
        
        
        Post newPost = new Post(postSubhead,postText,Picturepfad);        
        newPost.setCreator(null);
        newPost.setPost_versionNumber(post.getPost_versionNumber()+1);
        if(user!=null){            
            newPost.setCreator(user);
            System.err.println("der User wurde auch erkannt");
        }
        boolean existsInList=false;
        
        for (int i = 0; i < oldPosts.size(); i++) {
                int postid= Integer.parseInt(pid);
                if(oldPosts.get(i).getId()==postid){                    
                    newPosts.add(newPost);
                    existsInList=true;
                }else{
                    newPosts.add(oldPosts.get(i));
                }
	}
        if(!existsInList){
        newPosts.add(newPost);
    }
        
        Version newVersein = new Version((article.getVersions().size()+1),true,new Date(),newPosts);
        article.addVersions(newVersein);
        System.err.println("update?");
        em.update(article);
        System.err.println("ja");
        return SINGLE;
    }

    /**
     * Erstellt einen Article. Welcher Dierekt zur Datenbank hinzugefügt wird.
     *
     * @author Patrick Kuhlmann
     * @param thema Name des Artikels
     *
     * @return void
     */
    public void createArticle(String thema) {
        article = new Article(thema);
        em.persist(article);
    }

    public String goBack() {
        String aid;
        aid = getRequestParameter("id");
        if (aid != null) {
           searchArticle(aid);
           return SINGLE;
        }else{
            return INDEX;
        }        
    }
    
    public String goLogin(){
        return LOGIN;
    }
    
    public String goIndex(){
        return INDEX;
    }
    
    public String goKontakt(){
        return KONTAKT;
    }
    
    public String goImpressum(){
        return IMPRESSUM;
    }
   
    /**
     * Sucht nach einen bestimmten Article anhand der ID.
     *
     * @author Patrick Kuhlmann
     *
     * @param id des Article
     * @return der gesuchte Article
     */
    public Article searchArticle(String id) {
        this.article = em.getArticle(id);
        return this.article;
    }
    
    
    
    /**
     * Sucht nach einen bestimmten Post anhand der ID.
     *
     * @author Patrick Kuhlmann
     *
     * @param id des Posts
     * @return der gesuchte Post
     */
    public Post searchPost(String id) {
        this.post = em.getPost(id);
        return this.post;
    }
    

//Testfall! Gibt das Thema des ersten Article aus

    public void getThisArticle() {
        searchArticle("1");
    }
    //Testfall Ende

    public Article getArticle() {
        return article;
    }

    public void setArticle(Article article) {
        this.article = article;
    }

    public List<Article> getAllArticle() {
        List<Article> all =em.getAllArticle();
        if(all==null){
            return new ArrayList();
        }else{
        return  all;
        }
    }
    
    public List<Article> getLastTen() {
        List<Article> lastTen =em.LastTen();
        if(lastTen==null){
            return new ArrayList();
        }else{
        return  lastTen;
        }
    }

    /**
     * Zeigt einen bestimmten mit id gekennzeichneten Articel an.
     *
     * @author Patrick Kuhlmann
     *
     * @param id des Article
     * @return zielseite
     */
    public String show() {
        String fid = getRequestParameter("id");
        if (fid != null) {
            searchArticle(fid);
        }
        return SINGLE;
    }
    
    


    /**
     * Gibt die Posts der aktuellen version an. Ist keine bestimmte Version 
     * beschrieben wird die letzte Version genutzt.
     *
     * @author Patrick Kuhlmann
     *
     * @return Liste der Posts der Version
     */
    public Version getVersionPost() {
        String fid = getRequestParameter("versionid");
        String bid = getRequestParameter("id");
        searchText= getRequestParameter("searchText");
        if (searchText == null){
        if (fid != null) {
            searchArticle(bid);
            if (article != null) {
                System.err.println("Das bestimmte passiert +"+bid+"Version "+fid+" text"+searchText);
                Version spicialVersion = article.getVersion(Integer.parseInt(fid) - 1);
                return spicialVersion;
            } else {          
                    return null;                
            }
        } else {
            if (article != null) {
                System.err.println("Das passiert +"+bid+"Version "+fid+" text"+searchText);
                Version LastVersion = article.getLastVersion();
                return LastVersion;
            } else {
                return null;
            }
        }
        }else{
            System.err.println("Das suche passiert +"+bid+"Version "+fid+" text"+searchText);
            //in der Regel gibt es einen Articel
            if(article==null){
                Article temparticle = em.searchArticle(searchText).get(0);
                if(temparticle==null){
                    return article.getLastVersion();
                }else{
                    article=temparticle;
                    return article.getLastVersion();
                }
                
            } else{
            
                Version LastVersion = article.getLastVersion();
                return LastVersion;
            }
        }
    }
    
    /**
     * Macht nicht ausser einen aufruf dazustellen damit die Post Variablen 
     * versionid und id erneuert werden!
     *
     * @author Patrick Kuhlmann
     *
     */
    public void refreshVersion(){
    }

    public Post getPost() {
        return post;
    }

    public void setPost(Post post) {
        this.post = post;
    }
    
    public List<Post> getAllPost() {
        return em.getAllPosts();
    }

    private String getRequestParameter(String par) {
        return FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(par);
    }

    
    public String getPostText() {
        return postText;
    }

    public void setPostText(String postText) {
        this.postText = postText;
    }

    public Version getOldVersion() {
        return oldVersion;
    }

    public void setOldVersion(Version oldVersion) {
        this.oldVersion = oldVersion;
    }

    public String getPostSubhead() {
        return postSubhead;
    }

    public void setPostSubhead(String postSubhead) {
        this.postSubhead = postSubhead;
    }

    public String getArticleThema() {
        return articleThema;
    }

    public void setArticleThema(String articleThema) {
        this.articleThema = articleThema;
    }

    public String getSearchText() {
        return searchText;
    }

    public String toRegist(){
        return REGIST;
    }
    public boolean checkLink(String text){
         
        if((text.startsWith("["))&&(text.endsWith("]"))){
            if(em.searchArticle(convertLink(text)).isEmpty()){
            return false;
        }else{
            return true;
            }
        }else{
            return false;
        }
    }
    
    public String convertLink(String text){
        return text.substring(1, (text.length()-1));
    }
    public void setSearchText(String searchText) {
        this.searchText = searchText;
    }

    public void validateTextForm(FacesContext ctx, UIComponent comp,
    Object value) throws ValidatorException {
        
    if (value instanceof String) {
      String strValue = (String) value;
      boolean check=true;
      List<String> toValidate = getPostLinkPost(strValue);
      Iterator<String> iter = toValidate.iterator(); 
        while (iter.hasNext()) { 
            String s = iter.next(); 
            int a = s.indexOf("[",1);
            int b = s.indexOf("]");
            System.err.println("ma sehen:"+a+"mmmm"+b+"Text:"+s);
            if((a>0) || ((b<(s.length()-1))&&(b>=0))){
                System.err.println("Toll hat nicht geklappt:"+a+"mmmm"+b+"Text:"+s);
                check=false;
            }
        } 
      if (!check) {
        throw new ValidatorException(
            new FacesMessage("Bitte halte dich an die Formatierungsregeln", null));
      }
    } else {
        throw new ValidatorException(
            new FacesMessage("Da Stimmt was  nicht", null));
    }
}
    public void refreshVariables(){
        String aid,vid,pid;
        aid = getRequestParameter("id");
        vid = getRequestParameter("oldversionid");
        pid = getRequestParameter("postid");
        if (aid != null) {
             System.err.println("hierk komme isch schonma an 1");
           searchArticle(aid);
        }
         if (vid != null) {
              System.err.println("hierk komme isch schonma an 2");
           oldVersion = article.getVersion(Integer.parseInt(vid) - 1);
        }
         if (pid != null) {       
              System.err.println("hierk komme isch schonma an 3");
           if(searchPost(pid)==null){
               this.post=new Post("","","");
           }else{
               this.post=searchPost(pid);
           }
        }
    }
    
    public List<String> getPostLinkPost(String newPost) {         
        refreshVariables();
        List<String> Post_Link_Post = new ArrayList();
        int x = 0, y=0;
        while (x != -1) {

            x = newPost.indexOf("[");
            if ((x < (newPost.length())) && (x >= 0)) {
                Post_Link_Post.add(newPost.substring(y, x));
                y = newPost.indexOf("]", x + 1);
                if (y >= 0) {                   
                    String searchTempNaket =newPost.substring((x), (y+1));
                    newPost = newPost.substring((y+1), (newPost.length()));
                    y=0;
                    Post_Link_Post.add(searchTempNaket);
                }else{
                    newPost = newPost.substring((x), (newPost.length()));
                    y=0;
                }
            } else {
                
                Post_Link_Post.add(newPost.substring(0, (newPost.length())));
                x = -1;
            }
        }
        return Post_Link_Post;
    }
    
    /**
     * Erstellt Testwerte für die Seite. Nur in der Phase wo noch keine eingabe
     * möglich ist Sinnvoll.
     *
     * @author Patrick Kuhlmann
     */
    public void createTest() {

        
        User test = new User();
        test.setUser_name("edna");
        test.setUser_password("f5fa02bc60f633f3b1781a824f5211b5");
        
        
        
        Groups group = new Groups();
        group.setGroupid("basisuser");
        List<User> temp = new ArrayList();
        temp.add(test);
        group.setUser(temp);
        test.addGroup(group);
        //em.persist(group);
        
        User test2 = new User();
        test2.setUser_name("uwe");
        test2.setUser_password("c418f34f261efe1473465ade95bfc22c");
        
        Groups group2 = new Groups();
        group2.setGroupid("boss");        
        group2.addUser(test2);
        test2.addGroup(group2);
        //em.persist(group2);
        
        
        Article test_article = new Article("Mensch");
        Date date = new Date(2012, 2, 12);
        List<Post> posts = new ArrayList();
        posts.add(new Post("Urzeitmenschen", "Menschen, die vor vielen Jahre gelebt haben", "",test2));
        posts.add(new Post("Gattung Mensch", "Menschen sind [Säugetiere]", "",test2));
        test_article.addVersions(new Version(1, true, date, posts));
        date = new Date(2012, 2, 12);
        posts = new ArrayList();
        posts.add(new Post("Klimaerwärmung durch Menschen", "Das [Klima] erwärmt sich durch C02-Gase, welche durch Verbrennung von Fossilen Rohstoffen enstehen.", "",test2));
        posts.add(new Post("Klimaerwärmung schadet Säugetieren", "Durch die Klimaerwährung wird der Lebensraum für das größte Land-[Säugetier] verkleinert", "",test));
        test_article.addVersions(new Version(2, true, date, posts));
        em.update(test_article);

        Article test_articleZwei = new Article("Klima");
        date = new Date(2012, 2, 12);
        List<Post> postszwei = new ArrayList();
        postszwei.add(new Post("Klimaschutz", "Dies ist eine Maßnahme von dem [Mensch], welche die Klimaerwährung eindämmen soll", "",test));
        postszwei.add(new Post("Klimaerwärmung rottet Säugetiere aus", "[Säugetier]e, wie der Eisbär sind verlierer der Klimaerwährmung", "",test2));
        test_articleZwei.addVersions(new Version(1, true, date, postszwei));

        em.update(test_articleZwei);
        
        Article Saeugetier = new Article("Säugetier");
        date = new Date();
        List<Post> postsdrei = new ArrayList();
        postsdrei.add(new Post("Landsäugetier", "Ein Säugetier welches auf dem   Land lebt", "",test));
        Saeugetier.addVersions(new Version(1, true, date, postsdrei));
        
        em.update(Saeugetier);
        
        
        
//        User test2 = new User();
//        test.setUser_name("uwe");
//        test.setUser_password("c418f34f261efe1473465ade95bfc22c");
//        
//        
//        Groups group2 = new Groups();
//        group2.setGroupid("admin");
//        temp = new ArrayList();
//        temp.add(test2);
//        test2.addGroup(group2);
//        group2.setUser(temp);
//        em.persist(group2);
        
        
        
       
        
        
    }
}
